using Admin.Application.Common;
using Admin.Application.Dto;
using Admin.Application.Dto.Department;
using Admin.Application.Repositories;
using Admin.Domain.Entities;
using Admin.Domain.Repositories;

namespace Admin.Application.Services;

public class DepartmentService(IRepository<Department> departmentRepository, IRepository<User> userRepository, ISystemLogRepository logService) : IDepartmentService
{
    private readonly IRepository<Department> _departmentRepository = departmentRepository;
    private readonly IRepository<User> _userRepository = userRepository;
    private readonly ISystemLogRepository _logService = logService;

    public async Task<Result<string>> AddDepartmentAsync(DepartmentInfoDto departmentDto)
    {
        var department = Department.CreateDepartment(departmentDto.DepartmentName);
        if (department == null)
        {
            await _logService.AddAsync($"部门创建失败：名称为 {departmentDto.DepartmentName}");
            return Result<string>.Fail("部门创建失败");
        }

        await _departmentRepository.AddAsync(department);
        await _logService.AddAsync($"部门创建成功：{departmentDto.DepartmentName}");
        return Result<string>.Success("部门创建成功");
    }

    public async Task<Result<string>> DeleteDepartmentAsync(Guid departmentId)
    {
        var department = await _departmentRepository.GetByIdAsync(departmentId);
        if (department == null)
        {
            await _logService.AddAsync($"删除部门失败：部门不存在 - {departmentId}");
            return Result<string>.Fail("部门不存在");
        }

        var isDepartmentUpdated = department.DeleteDepartment();
        if (!isDepartmentUpdated)
        {
            await _logService.AddAsync($"删除部门失败：删除失败 - {departmentId}");
            return Result<string>.Fail("部门删除失败");
        }

        await _departmentRepository.UpdateAsync(department);
        await _logService.AddAsync($"删除部门成功：{department.DepartmentName}");
        return Result<string>.Success("部门删除成功");
    }

    public async Task<Result<ResDepartmentDto?>> GetDepartmentByIdAsync(Guid departmentId)
    {
        var department = await _departmentRepository.GetByIdAsync(departmentId);
        if (department == null)
        {
            await _logService.AddAsync($"查询部门失败：部门不存在 - {departmentId}");
            return Result<ResDepartmentDto?>.Fail("部门不存在");
        }

        string? parentName = null;
        if (department.ParentId.HasValue)
        {
            var parentDepartment = await _departmentRepository.GetByIdAsync(department.ParentId.Value);
            parentName = parentDepartment?.DepartmentName;
        }

        string? managerName = null;
        if (department.ManagerId.HasValue)
        {
            var manager = await _userRepository.GetByIdAsync(department.ManagerId.Value);
            managerName = manager?.UserName;
        }

        var childrenNames = string.Join(",", department.Children.Select(c => c.DepartmentName));
        var userNames = string.Join(",", department.Users.Select(u => u.UserName));

        var resDepartmentDto = new ResDepartmentDto(
            department.Id,
            department.DepartmentName,
            parentName,
            managerName,
            department.IsActive,
            department.Description,
            childrenNames,
            userNames
        );

        await _logService.AddAsync($"查询部门成功：{department.DepartmentName}");
        return Result<ResDepartmentDto?>.Success(resDepartmentDto);
    }

    public async Task<Result<List<ResDepartmentDto>>> GetPagedDepartmentAsync(int pageIndex, int pageSize)
    {
        if (pageIndex < 0 || pageSize < 0)
        {
            await _logService.AddAsync($"分页查询部门失败：无效的页码或数据条数 - 页码：{pageIndex}，条数：{pageSize}");
            return Result<List<ResDepartmentDto>>.Fail("无效的页码或数据条数");
        }

        var departmentList = await _departmentRepository.GetPagedAsync(pageIndex, pageSize);

        var resDepartmentDtoTasks = departmentList.Select(async d =>
        {
            string? parentName = null;
            if (d.ParentId.HasValue)
            {
                var parentDepartment = await _departmentRepository.GetByIdAsync(d.ParentId.Value);
                parentName = parentDepartment?.DepartmentName;
            }

            string? managerName = null;
            if (d.ManagerId.HasValue)
            {
                var manager = await _userRepository.GetByIdAsync(d.ManagerId.Value);
                managerName = manager?.UserName;
            }

            var childrenNames = string.Join(",", d.Children.Select(c => c.DepartmentName));
            var userNames = string.Join(",", d.Users.Select(u => u.UserName));

            return new ResDepartmentDto(
                d.Id,
                d.DepartmentName,
                parentName,
                managerName,
                d.IsActive,
                d.Description,
                childrenNames,
                userNames
            );
        });

        var resDepartmentDtoList = await Task.WhenAll(resDepartmentDtoTasks);

        await _logService.AddAsync($"分页查询部门成功：页码 {pageIndex}，条数 {pageSize}");
        return Result<List<ResDepartmentDto>>.Success([.. resDepartmentDtoList]);
    }

    public async Task<Result<string>> UpdateDepartmentInfoAsync(Guid departmentId, DepartmentInfoDto departmentDto)
    {
        var department = await _departmentRepository.GetByIdAsync(departmentId);
        if (department == null)
        {
            await _logService.AddAsync($"更新部门信息失败：部门不存在 - {departmentId}");
            return Result<string>.Fail("部门不存在");
        }

        bool isDepartmentUpdated = department.UpdateDepartmentInfo(departmentDto.DepartmentName, departmentDto.Description);
        if (!isDepartmentUpdated)
        {
            await _logService.AddAsync($"更新部门信息失败：更新失败 - {departmentId}");
            return Result<string>.Fail("部门信息更新失败");
        }

        await _departmentRepository.UpdateAsync(department);
        await _logService.AddAsync($"更新部门信息成功：{department.DepartmentName}");
        return Result<string>.Success("部门信息更新成功");
    }

    public async Task<Result<string>> UpdateDepartmentManagerAsync(Guid departmentId, Guid? managerID)
    {
        var department = await _departmentRepository.GetByIdAsync(departmentId);
        if (department == null)
        {
            await _logService.AddAsync($"更新部门负责人失败：部门不存在 - {departmentId}");
            return Result<string>.Fail("部门不存在");
        }

        var isDepartmentUpdated = department.UpdateManagerId(managerID);
        if (!isDepartmentUpdated)
        {
            await _logService.AddAsync($"更新部门负责人失败：更新失败 - {departmentId}");
            return Result<string>.Fail("部门负责人更新失败");
        }

        await _departmentRepository.UpdateAsync(department);
        await _logService.AddAsync($"更新部门负责人成功：{department.DepartmentName}");
        return Result<string>.Success("部门负责人更新成功");
    }

    public async Task<Result<string>> UpdateDepartmentParentAsync(Guid departmentId, Guid? parentId)
    {
        var department = await _departmentRepository.GetByIdAsync(departmentId);
        if (department == null)
        {
            await _logService.AddAsync($"更新部门上级失败：部门不存在 - {departmentId}");
            return Result<string>.Fail("部门不存在");
        }

        if (department.ParentId.HasValue)
        {
            var currentParent = await _departmentRepository.GetByIdAsync(department.ParentId.Value);
            if (currentParent != null)
            {
                currentParent.RemoveChildrenDepartment(department);
                department.UpdateParentId(null);
                await _departmentRepository.UpdateAsync(currentParent);
                await _departmentRepository.UpdateAsync(department);
            }
        }

        if (parentId.HasValue)
        {
            var newParent = await _departmentRepository.GetByIdAsync(parentId.Value);
            if (newParent == null)
            {
                await _logService.AddAsync($"更新部门上级失败：新上级部门不存在 - {parentId}");
                return Result<string>.Fail("新上级部门不存在");
            }

            newParent.AddChildrenDepartment(department);
            await _departmentRepository.UpdateAsync(newParent);
        }

        department.ParentId = parentId;
        await _departmentRepository.UpdateAsync(department);

        await _logService.AddAsync($"更新部门上级成功：{department.DepartmentName}");
        return Result<string>.Success("部门上级部门更新成功");
    }

    public async Task<Result<string>> UpdateIsActive(Guid departmentId, ActiveDto activeDto)
    {
        var department = await _departmentRepository.GetByIdAsync(departmentId);
        if (department == null)
        {
            await _logService.AddAsync($"更新部门启用状态失败：部门不存在 - {departmentId}");
            return Result<string>.Fail("部门不存在");
        }

        bool isDepartmentUpdated;
        if (activeDto.IsActive)
        {
            isDepartmentUpdated = department.EnableRole();
        }
        else
        {
            isDepartmentUpdated = department.DisableRole();
        }

        if (!isDepartmentUpdated)
        {
            await _logService.AddAsync($"更新部门启用状态失败：更新失败 - {departmentId}");
            return Result<string>.Fail("部门启用状态更新失败");
        }

        await _departmentRepository.UpdateAsync(department);
        await _logService.AddAsync($"更新部门启用状态成功：{department.DepartmentName}");
        return Result<string>.Success("部门启用状态更新成功");
    }
}